home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / VISITYPE.ASM < prev    next >
Assembly Source File  |  1987-01-28  |  15KB  |  316 lines

  1. VECTORS SEGMENT AT 0H           ;Set up segment to intercept Interrupts
  2.         ORG     9H*4            ;The keyboard Interrupt
  3. KEYBOARD_INT     LABEL   WORD
  4.         ORG     1CH*4           ;Timer Interrupt
  5. TIMER_VECTOR      LABEL   WORD
  6. VECTORS ENDS
  7.  
  8. SCREEN  SEGMENT AT 0B000H       ;A dummy segment to use as the
  9. SCREEN  ENDS                    ;Extra Segment 
  10.  
  11. ROM_BIOS_DATA   SEGMENT AT 40H  ;BIOS statuses held here, also keyboard buffer
  12.  
  13.         ORG     1AH
  14.         HEAD DW      ?                  ;Unread chars go from Head to Tail
  15.         TAIL DW      ?
  16.         BUFFER       DW      16 DUP (?)         ;The buffer itself
  17.         BUFFER_END   LABEL   WORD
  18.  
  19. ROM_BIOS_DATA   ENDS
  20.  
  21. CODE_SEG        SEGMENT
  22.         ASSUME  CS:CODE_SEG
  23.         ORG     100H               ;ORG = 100H to make this into a .COM file
  24. FIRST:  JMP     LOAD_BUFFER        ;First time through 
  25.  
  26.         COPY_RIGHT      DB      'Copyright 1986 Ziff-Davis Publishing Co.'
  27.         BUFF            DW      0
  28.         BUFF2           DW      159 DUP(0)
  29.         PAD_OFFSET      DW      0               ;Chooses 1st 160 bytes or 2nd
  30.         SCREEN_SEG_OFFSET       DW      0       ;0 for mono, 8000H for graphics
  31.         IO_CHAR         DW      1               ;Holds addr of Put or Get_Char
  32.         OLD_HEAD        DW      1               ;To check for typeahead.
  33.         DISPLAY_ON      DB      0               ;0 --> Off.
  34.         STATUS_PORT     DW      0               ;Video controller status port
  35.         NEAR_ATTRIB_FLAG        DB      0       ;Used in Put_Char
  36.         OLD_KEYBOARD_INT_LABEL  LABEL   DWORD
  37.         OLD_KEYBOARD_INT        DW      0       ;Location of old kbd interrupt 
  38.                                 DW      0
  39.         ROM_TIMER_LABEL         LABEL   DWORD
  40.         ROM_TIMER               DW      0       ;The Timer interrupt's address
  41.                                 DW      0
  42.  
  43. BUFSTUFF PROC    NEAR            ;The keyboard interrupt will now come here.
  44.         ASSUME  CS:CODE_SEG
  45.         PUSH    AX              ;Save the used registers for good form
  46.         PUSH    BX
  47.         PUSH    CX
  48.         PUSH    DX
  49.         PUSH    DI
  50.         PUSH    SI
  51.         PUSH    DS
  52.         PUSH    ES
  53.         PUSHF                           ;First, call old keyboard interrupt
  54.         CALL    OLD_KEYBOARD_INT_LABEL
  55.         ASSUME  DS:ROM_BIOS_DATA        ;Examine the char just put in
  56.         MOV     BX,ROM_BIOS_DATA
  57.         MOV     DS,BX
  58.         MOV     BX,TAIL                 ;Point to current tail
  59.         CMP     BX,HEAD                 ;If at head, kbd int has deleted char
  60.         JNE     CONT
  61.         JMP     OUT                     ;So leave 
  62. CONT:   MOV     DX,TAIL                 ;Read a char -- head advances.
  63.         SUB     DX,2                    ;Point to just read in character
  64.         CMP     DX,OFFSET BUFFER        ;Did we undershoot buffer?
  65.         JAE     NOWRAP                  ;Nope
  66.         MOV     DX,OFFSET BUFFER_END    ;Yes -- move to buffer top
  67.         SUB     DX,2                    
  68. NOWRAP: MOV     BX,DX
  69.         MOV     CX,[BX]                 ;Get key in CX
  70.         CMP     CX,BUFF                 ;Is it where we were before?
  71.         JNE     T10
  72.         MOV     BX,HEAD                 ;Has the head moved?
  73.         CMP     BX,OLD_HEAD
  74.         JE      T11                     ;If yes, we have moved.
  75. T10:    CMP     BUFF2,0
  76.         JNE     REMOVE                  ;If there's something in BUFF2,
  77. T11:    CMP     DX,HEAD                 ; remove char in kbd buffer.
  78.         JNE     REMOVE
  79.         JMP     OUT                     ;Do nothing this pass.
  80.         ;More than one char in buffer -- Remove One!
  81. REMOVE: MOV     BX,DX
  82.         MOV     TAIL,DX                 ;Remove character by adjusting tail.
  83.         MOV     DX,[BX]                 ;Store character in buffer.
  84.         MOV     CX,80
  85.         MOV     BX,0                    ;Find end of visitype buffer.
  86. CHECK:  CMP     BUFF2[BX],0
  87.         JE      BUFEND
  88.         ADD     BX,2
  89.         LOOP    CHECK
  90.         CMP     DX,0E08H                ;Was this key a rubout?
  91.         JNE     OUT                     ;No, and buffer filled -- leave.
  92.         MOV     BX,158                  ;Yes, buff full but rubout last char.
  93.         MOV     WORD PTR BUFF[BX],0
  94.         MOV     BX,HEAD
  95.         MOV     OLD_HEAD,BX             ;Store this for next time.
  96.         MOV     DX,[BX]                 ;Always load BUFF.
  97.         MOV     BUFF,DX
  98.         JMP     OUT                     ;Can't hold more than 80!
  99. BUFEND: CMP     DX,0E08H                ;Rubout (and buffer not full)?
  100.         JNE     NODEL                   ;No, don't del.
  101. DEL:    SUB     BX,2                    ;Yes, delete last key.
  102.         CMP     BX,0FFFEH               ;Gone too far?
  103.         JL      OUT
  104.         JNE     PADDEL
  105.         MOV     CX,TAIL                 ;Del the one char in kdb buffer
  106.         MOV     HEAD,CX                 ; by making tail = head.
  107.         MOV     BUFF,0
  108.         JMP     SHORT CHKDIS
  109. PADDEL: MOV     DX,0                    ;DX --> 0 if we are deleting.
  110. NODEL:  MOV     BUFF2[BX],DX            ;Load key in Visitype buffer.
  111.         MOV     BX,HEAD
  112.         MOV     OLD_HEAD,BX             ;And store the old head to check later.
  113.         MOV     DX,[BX]                 ;Always reload BUFF.
  114.         MOV     BUFF,DX
  115. CHKDIS: CMP     DISPLAY_ON,0            ;Are we on?
  116.         JNE     FLASH                   ;Yes, call DISPLAY
  117.         MOV     DISPLAY_ON,0FFH         ;Store what's on the screen first.
  118.         MOV     PAD_OFFSET,160          
  119.         LEA     AX,GET_CHAR             ;Make IO use Get-Char so it does.
  120.         MOV     IO_CHAR,AX              
  121.         CALL    IO                      ;Get top line from screen.
  122. FLASH:  CALL    DISPLAY                 ;Display VISITYPE's top line.
  123. OUT:    POP     ES                      ;Having done Pushes, here are the Pops
  124.         POP     DS
  125.         POP     SI
  126.         POP     DI
  127.         POP     DX
  128.         POP     CX
  129.         POP     BX
  130.         POP     AX     
  131.         IRET                            ;An interrupt needs an IRET
  132. BUFSTUFF ENDP
  133.  
  134. DISPLAY PROC    NEAR                    ;Puts the whole pad on the screen
  135.         PUSH    AX
  136.         MOV     NEAR_ATTRIB_FLAG,0
  137.         MOV     PAD_OFFSET,0            ;Use 1st bytes of pad memory
  138.         LEA     AX,PUT_CHAR             ;Make IO use Put-Char so it does
  139.         MOV     IO_CHAR,AX              
  140.         CALL    IO                      ;Put result on screen
  141.         POP     AX
  142.         RET                             ;Leave
  143. DISPLAY ENDP
  144.  
  145. GET_CHAR        PROC    NEAR    ;Gets a char from screen and advances position
  146.         ASSUME  ES:SCREEN,DS:ROM_BIOS_DATA
  147.         PUSH    DX
  148.         MOV     SI,2            ;Loop twice, once for char, once for attribute
  149.         MOV     DX,STATUS_PORT  ;Get ready to read video controller status
  150. G_WAIT_LOW:                     ;Start waiting for a new horizontal scan -
  151.         IN      AL,DX           ;Make sure the video controller scan status
  152.         TEST    AL,1            ;is low
  153.         JNZ     G_WAIT_LOW
  154. G_WAIT_HIGH:                    ;After port has gone low, it must go high
  155.         IN      AL,DX           ;before it is safe to read directly from
  156.         TEST    AL,1            ;the screen buffer in memory
  157.         JZ      G_WAIT_HIGH
  158.         MOV     AX,ES:[DI]      ;Do the move from the screen, one byte at a time
  159.         INC     DI              ;Move to next screen location                   
  160.         DEC     SI              ;Decrement loop counter
  161.         CMP     SI,0            ;Are we done?
  162.         JE      LEAVE           ;Yes
  163.         MOV     BUFF[BX],AX     ;No -- put char we got into BUFF.
  164.         JMP     G_WAIT_LOW      ;Do it again
  165. LEAVE:  ADD     BX,2
  166.         POP     DX
  167.         RET
  168. GET_CHAR        ENDP
  169.  
  170. PUT_CHAR        PROC    NEAR    ;Puts one char on screen and advances position
  171.         PUSH    DX
  172.         CLI
  173.         MOV     AH,BYTE PTR BUFF[BX]      
  174.         MOV     SI,2            ;Loop twice, once for char, once for attribute
  175.         MOV     DX,STATUS_PORT  ;Get ready to